package cn.itcast.demo;

import cn.itcast.EsApplication;
import cn.itcast.demo.pojo.Item;
import cn.itcast.demo.repository.ItemRepository;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = EsApplication.class)
public class SelfAggDemo {

    @Autowired
    private ItemRepository itemRepository;


    @Test
    public void testAggs(){

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加聚合条件
        queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand"));

        //聚合的结果在page中，但是要获取到聚合的结果需要把类型转换为AggregatedPage，只有它才有这个方法
        AggregatedPage<Item> itemPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());

        //从聚合结果中获取一个叫brands的聚合,由于参与聚合的字段的类型为String，所以聚合结果要纳入StringTerms，如果聚合字段类型为Long，结果就是longTerms
        StringTerms brands = (StringTerms) itemPage.getAggregation("brands");

        List<StringTerms.Bucket> buckets = brands.getBuckets();

        buckets.forEach(bucket -> {

            String key = bucket.getKeyAsString();
            long docCount = bucket.getDocCount();

            System.out.println(key+" 总共有："+docCount);

        });

    }


    @Test
    public void testAggsAndSubAgg(){

        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //添加聚合条件
        queryBuilder.addAggregation(AggregationBuilders.terms("brands").field("brand")
        .subAggregation(AggregationBuilders.avg("avg-price").field("price")));

        //聚合的结果在page中，但是要获取到聚合的结果需要把类型转换为AggregatedPage，只有它才有这个方法
        AggregatedPage<Item> itemPage = (AggregatedPage<Item>) this.itemRepository.search(queryBuilder.build());

        //从聚合结果中获取一个叫brands的聚合,由于参与聚合的字段的类型为String，所以聚合结果要纳入StringTerms，如果聚合字段类型为Long，结果就是longTerms
        StringTerms brands = (StringTerms) itemPage.getAggregation("brands");

        List<StringTerms.Bucket> buckets = brands.getBuckets();

        buckets.forEach(bucket -> {

            String key = bucket.getKeyAsString();
            long docCount = bucket.getDocCount();

            //获取所有的聚合结果,吧聚合结果转为map

            InternalAvg internalAvg = (InternalAvg) bucket.getAggregations().asMap().get("avg-price");

            System.out.println(key+" 总共有："+docCount+",平均价格："+internalAvg.getValue());

        });


    }
}